package com.minedata.authorization.config;

import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.minedata.authorization.bean.ModuleBean;
import com.minedata.authorization.bean.UserBean;
import com.minedata.authorization.service.ModuleService;

@Component
public class StatelessAccessControlFilter extends AccessControlFilter {
	
	@Autowired
	private ModuleService moduleService;
	
	@Override
	protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
			throws Exception {
		String curUrl = request.getParameter("url");

		String[] regEx = {"/error",
						"/service/user/tencent/register",
				        "/service/user/register",
						"/service/user/login",
						//"/service/user/sendVer/[a-zA-Z_]{1,}[0-9]{0,}@(([a-zA-z0-9]-*){1,}\\.){1,3}[a-zA-z\\-]{1,}",
						"/service/user/sendVer",
						"/service/user/verification",
						"/service/user/sendVer",
						"/service/user/verify",
						"/service/user/expiry",
						"/service/user/unique",
						"/service/user/role/[0-9]+",
						"/service/user/tencent/register",
						"/service/user/tencent/login",
						"/service/user/tencent/verification",
						"/service/token/list/solu/edit",
						"/service/token/list/solu/query",
						"/service/source/[0-9]+",
						"/service/source/list",
						"/service/source/tileJson/[0-9]+",
						"/service/source/layerDesc/[0-9]+",
						"/service/source/group/list",
						"/service/source/group/list/[0-9]*",
						"/service/source/statistic/[0-9]+",
						"/service/solu/template/list",
						"/service/solu/import",
						"/service/solu/export",
						"/service/solu/[0-9]+",
						"/service/solu/style/id/[0-9]+",
						"/service/solu/style/id/[0-9]+",
						"/service/search/*",
						"/service/route/*",
						"/service/coder/*",
						"/service/tips/*",
						"/service/contact/send"
						};

		for(String strEx : regEx){
			if(strEx.endsWith("*")){
				if(curUrl.startsWith(strEx.replace("*", ""))){
					return true;
				}
			}
			else{
				Pattern pattern = Pattern.compile(strEx);
				Matcher matcher = pattern.matcher(curUrl);
				if(matcher.matches()){
					return true;
				}
			}
		}
		return false;
	}

	@Override
	protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
		System.out.println("StatelessAuthcFilter.onAccessDenied()");
		String curUrl = request.getParameter("url");
		
		// 1、客户端生成的消息摘要
		String digest = request.getParameter("digest");

		// 2、客户端传入的用户身份
		String username = request.getParameter("username");

		// 2、客户端传入的用户身份
		String id = request.getParameter("digestId");
		
		// 4、生成无状态Token
		StatelessAuthenticationToken token = null;
		if(id == null)
			token = new StatelessAuthenticationToken(username, digest);
		else{
			token = new StatelessAuthenticationToken(Integer.parseInt(id), digest);
		}

		Subject subject = null;
		try {
			// 5、委托给Realm进行登录
			subject = getSubject(request, response);
			subject.login(token);
		} catch (Exception e) {
			//e.printStackTrace();
			// 6、登录失败
			onLoginFail(response);
			return false;// 就直接返回给请求者.
		}
		
		UserBean userBean=(UserBean) subject.getPrincipal();
		
		List<ModuleBean> list = moduleService.findModuleByUserId(userBean.getId());
		
		for(ModuleBean moduleBean : list){
			String url = moduleBean.getUrl();
			if(url.endsWith("*")){
				if(curUrl.startsWith(url.replace("*", ""))){
					return true;
				}
			}
		}
		onAuthFail(response);
		return false;
	}
	
	// 登录失败时默认返回401 状态码
	private void onAuthFail(ServletResponse response) throws IOException {
		HttpServletResponse httpResponse = (HttpServletResponse) response;
		httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
		JSONObject json = new JSONObject();
		json.put("errcode", 2);
		json.put("errmsg", "auth fail");	
		httpResponse.getWriter().write(json.toJSONString());
	}

	// 登录失败时默认返回401 状态码
	private void onLoginFail(ServletResponse response) throws IOException {
		HttpServletResponse httpResponse = (HttpServletResponse) response;
		httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
		JSONObject json = new JSONObject();
		json.put("errcode", 1);
		json.put("errmsg", "login fail");	
		httpResponse.getWriter().write(json.toJSONString());
	}
}
